package com.qf.controller;

import com.alibaba.fastjson.JSONObject;
import com.qf.constant.Constant;
import com.qf.convert.DateConvert;
import com.qf.pojo.BaseResult;
import com.qf.pojo.User;
import com.qf.service.UserService;
import com.qf.service.impl.UserServiceImpl;
import com.qf.utils.MD5Utils;
import com.qf.utils.UUIDUtils;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.net.URLEncoder;
import java.util.Date;
import java.util.Map;

/**
 * @author 高圆圆
 * @date 2023/6/1 16:00
 * 用户模块
 * servlet提供的注解方式代替 xml配置方式
 *      web.xml
 *              <servlet-name>默认就是类名</servlet-name>
 *              <servlet-class>com.qf.controller.UserServlet</servlet-class>
 *              <servlet-mapping>
 *                    <servlet-name>默认就是类名</servlet-name>
 *                    <url-pattern>/user</url-pattern>
 *              </servlet-mapping>
 *
 *
 *
 *  注解---本质是interface   @interface
 *
 *   http://localhost:8080/web上下文/user?methodName=add
 */
@WebServlet("/user" )//urlPatterns属性和value一致
public class UserServlet  extends BaseServlet{
    //定义的子类的方法名
   /* public void add(HttpServletRequest request, HttpServletResponse response){

        System.out.println("add方法被调用了...");
    }*/

    /**
     * 前台异步校验用户名的功能
     * @param request 请求对象
     * @param response 响应对象
     */
    public void checkUser(HttpServletRequest request,
                          HttpServletResponse response)
            throws IOException {

        //"${pageContext.request.contextPath}/checkUser?username="+username
        String username = request.getParameter("username") ;

        //调用前台用户业务接口UserService
        UserService userService = new UserServiceImpl() ;
        BaseResult baseResult = userService.checkUserByUsername(username);

        //创建Fastjson的解析器
        JSONObject jsonObject  = new JSONObject() ;
        String jsonString = jsonObject.toJSONString(baseResult);
        //响应给前端
        response.getWriter().write(jsonString) ;
    }

    /**
     * 前台用户注册功能
     * @param request 请求对象
     * @param response 响应对象
     */
    public void registerUser(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {

        //1)先校验验证码
        //接收前端输入的验证码
        String code = request.getParameter("code");
        /**
         * HttpSession getSession(boolean var1); 参数为true:表示创建会话
         *                                      参数为false,表示已经存在会话,获取HttpSession
         *
         * HttpSession getSession(); 在服务器端自己判断,等价于创建Session,HttpSession getSession(boolean var1); 参数为true:表示创建会话
         *                          如果有session,也会使用空参构造方法
         */
        HttpSession session = request.getSession() ;
        //取出存储的验证码
        String checkcode_server = (String) session.getAttribute("CHECKCODE_SERVER");

        //验证码是一次性验证(只要输入的验证码提示错误,必须把之前绑定的图片的随机数删除)
        session.removeAttribute("CHECKCODE_SERVER") ;
        //如果前端输入的code的内容是空,或者是空字符串   code的内容和服务器端存储的内容不一致
        if(code==null || "".equals(code) || !checkcode_server.equalsIgnoreCase(code)){
            request.setAttribute("msg","验证码输入错误") ;         //request域存储一个信息
            //请求转发到注册页面上
            request.getRequestDispatcher("/jsp/register.jsp").forward(request,response);
            return;
        }


        //接收前端提交的参数:使用Map
        Map<String, String[]> map = request.getParameterMap(); //包含了birthday日期参数
        //封装User对象
        User user = new User() ;
        System.out.println(user) ;


        //使用commons-beanUtils.jar包---BeanUtils工具类的populate(实体对象,map)

        //在BeanUtils.populate(user,map) ;封装user数据,就出现异常,无法将String的日期文本---封装java.util.Date
        //封装之前需要对日期进行处理,commons-beanUtils.jar包--工具类:转换工具类
        //ConvertUtils--->public static void register(Converter converter, Class clazz)
        //参数1:转换器接口--自定义类实现这个接口
        //参数2:目标类型的字节码文件对象
        ConvertUtils.register(new DateConvert(), Date.class);
        try {
            BeanUtils.populate(user,map) ;
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        //System.out.println(user);

        //用户的uid---UUID产生随机字符串
        user.setUid(UUIDUtils.getId()) ;
        //密码需要加密
        user.setPassword(MD5Utils.md5(user.getPassword()));
        //state:状态码默认值0
        user.setCode(UUIDUtils.getCode());


        //调用用户的业务接口
        UserService userService = new UserServiceImpl() ;
        userService.register(user) ;


        //请求转发到消息提示页
        request.setAttribute("msg","恭喜您,注册成功!");
        request.getRequestDispatcher("/jsp/message.jsp").forward(request,response);

    }

    /**
     * 用户激活的功能
     * @param request 请求对象
     * @param response 响应对象
     */
    public void userActive(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {

        // http://localhost:8080/Servlet_Jdbc_Jsp_war_exploded/user?methodName=userActive&usercode=xxxxxx
        //接收参数
        String usercode = request.getParameter("usercode");
        //调用servcie
        UserService userService = new UserServiceImpl() ;
        User user = userService.getUserByCode(usercode);
        if(user!=null){
            //更新完成之后
            request.setAttribute("msg","用户激活完成,请<a href='http://localhost:8080/Servlet_Jdbc_Jsp_war_exploded/jsp/login.jsp'>登录</a>");
            request.getRequestDispatcher("/jsp/message.jsp").forward(request,response);
        }
    }

    /**
     * 前台用户登录功能
     * @param request 请求对象
     * @param response 响应对象
     */
    public void user_login(HttpServletRequest request,HttpServletResponse response) throws IOException,
            ServletException {
        //1)先校验验证码
        String code = request.getParameter("code");
        //获取服务器端存储的验证码
        HttpSession session = request.getSession();
        String checkcode_server = (String) session.getAttribute("CHECKCODE_SERVER");

        //一次性校验
        session.removeAttribute("CHECKCODE_SERVER");
        if(code == null || "".equals(code)|| !checkcode_server.equalsIgnoreCase(code)){
            //错误提示
            request.setAttribute("msg","验证码输入错误") ;
            request.getRequestDispatcher("/jsp/login.jsp").forward(request,response) ;
            return;
        }

        //2)接收用户名和密码
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        //密码加密之后,传递到业务层中
        password = MD5Utils.md5(password) ;


        //3)调用业务接口
        UserService userService = new UserServiceImpl() ;
        //通过用户名和密码---获取到user对象
        User user = userService.login(username,password) ;

        //4)判断
        if(user==null){
            //错误提示
            request.setAttribute("msg","用户名或者密码输入错误") ;
            request.getRequestDispatcher("/jsp/login.jsp").forward(request,response) ;
        }

        //如果user不能等于null
        //判断user的激活状态是否为1
        if(Constant.USER_ACTIVE_STATE !=user.getState()){
            request.setAttribute("msg","用户状态是未激活状态") ;
            request.getRequestDispatcher("/jsp/login.jsp").forward(request,response) ;
        }

        //判断用户是否勾选自动登录
        //获取 name="autoUser" 的内容(勾选的状态)
        String autoUser = request.getParameter("autoUser");
        //使用获取状态值和复选框的默认值value="auto_user"进行比对
        if(!"auto_user".equals(autoUser)){
            //没有勾选
            //会删除cookie
            Cookie cookie = new Cookie("autouser","") ;
            //有效期 0,自动删除cookie
            cookie.setMaxAge(0) ;
            response.addCookie(cookie) ;
        }else{
            //勾选了
            //获取用户名和密码(加密后的密码)
            String uname = user.getUsername();//昵称
            String upass = user.getPassword();//密码
            //将这个两个组装成cookie的内容,约定一种格式 "昵称=密码"
            String content = uname+"="+upass ;
            //将content内容进行加密--jdk提供了加密工具URLEncoder
            //静态方法:public static String encode(String s,String enc):参数1:内容 参数2:字符集格式
            content = URLEncoder.encode(content,"utf-8") ;
            //创建cookie
            Cookie cookie = new Cookie("autouser",content) ;
            //设置有效期
            cookie.setMaxAge(60*60*24*30) ;
            //响应给浏览器端存储
            response.addCookie(cookie) ;
        }


        //将user对象存储在HttpSession中
        session.setAttribute("user",user) ;
        //重定向到前台主页地址
        response.sendRedirect(request.getContextPath()+"/jsp/index.jsp") ;

    }

    /**
     *前台 用户退出功能
     * @param request 请求对象
     * @param response 响应对象
     */
    public void userLogout(HttpServletRequest request,HttpServletResponse response) throws IOException {
        //获取session
        HttpSession session = request.getSession();
        session.invalidate(); //取消对任何数据的绑定,(暴力删除)
        //重定向到前台主页
        response.sendRedirect(request.getContextPath()+"/jsp/index.jsp");
    }







}
